package com.ecarx.vhaltests.hy11.testcases.climate;

import android.car.VehicleAreaSeat;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacFanDirectionTest extends VhalUnitTestBase {
    private static final String TAG = "HvacFanDirectionTest";
    private static  int directionValue_front;
    private static  int directionValue_second;


    private static final int HVAC_FAN_DIRECTION = VehiclePropertyIds.HVAC_FAN_DIRECTION;
    private static final int HVAC_FAN_DIRECTION_FRONT_AREA = VehicleAreaSeat.SEAT_ROW_1_LEFT | VehicleAreaSeat.SEAT_ROW_1_RIGHT; ;
    private static final int HVAC_FAN_DIRECTION_SECOND_AREA = VehicleAreaSeat.SEAT_ROW_2_LEFT | VehicleAreaSeat.SEAT_ROW_2_RIGHT;

    public static final int BLOWING_MODE_OFF = 0;
    public static final int BLOWING_MODE_FACE  =  1;
    public static final int BLOWING_MODE_LEG  =  2;
    public static final int BLOWING_MODE_FACE_AND_LEG  =  3;
    public static final int BLOWING_MODE_FRONT_WINDOW  =  4;
    public static final int BLOWING_MODE_FACE_AND_FRONT_WINDOW  =  5;
    public static final int BLOWING_MODE_LEG_AND_FRONT_WINDOW  =  6;
    public static final int BLOWING_ALL  =  7;


    private static final int SERVICE_ID_CLIMATE = 112;
    private static final int OP_ID_CLIMATE = 0xc8;

    static final Object lock_front = new Object();
    static final Object lock_second = new Object();
    static IpcpClient ipcpClient = new IpcpClient();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, HVAC_FAN_DIRECTION, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig(OP_ID_CLIMATE);
    }

    @Test //吹风模式设置前排有效测试
    public void test01_HvacFanDirectionAvail() {
        PrepareHvacFanDirectionTestEnv( HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionAvailTest( true, HVAC_FAN_DIRECTION_FRONT_AREA );
    }

    @Test //设置吹风模式第二排配置
    public void test02_HvacFanDirectionAvail() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_SECOND_AREA ,1,0);
        delay();
        HvacFanDirectionAvailTest( true, HVAC_FAN_DIRECTION_SECOND_AREA );
    }

    @Test  //吹风模式设置前排无效测试
    public void test03_HvacFanDirectionNotAvail() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,3,0);
        delay();
        HvacFanDirectionAvailTest( false, HVAC_FAN_DIRECTION_FRONT_AREA );
    }

    @Test  //吹风模式设置前排无效测试
    public void test04_HvacFanDirectionNotAvail() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_SECOND_AREA,3,0);
        delay();
        HvacFanDirectionAvailTest( false,HVAC_FAN_DIRECTION_SECOND_AREA);
    }

    @Test //前排吹风模式-吹面
    public void test05_HvacFanDirectionSetModeFace() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_FRONT_AREA,BLOWING_MODE_FACE);
    }

    @Test //前排吹风模式-吹地
    public void test06_HvacFanDirectionSetModeLeg() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_FRONT_AREA,BLOWING_MODE_LEG);
    }

    @Test //前排吹风模式-吹地+吹面
    public void test07_HvacFanDirectionSetModeFaceAndLeg() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_FRONT_AREA,BLOWING_MODE_FACE_AND_LEG);
    }

    @Test //前排吹风模式-吹窗
    public void test08_HvacFanDirectionSetModeWindow() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_FRONT_AREA,BLOWING_MODE_FRONT_WINDOW);
    }

    @Test //前排吹风模式-吹面+吹窗
    public void test09_HvacFanDirectionSetModefaceAndWindow() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_FRONT_AREA,BLOWING_MODE_FACE_AND_FRONT_WINDOW);
    }

    @Test //前排吹风模式-吹地+吹窗
    public void test10_HvacFanDirectionSetModeLegAndWindow() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_FRONT_AREA,BLOWING_MODE_LEG_AND_FRONT_WINDOW);
    }

    @Test //前排吹风模式-吹地+吹面+吹窗
    public void test11_HvacFanDirectionSetModeAll() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_FRONT_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_FRONT_AREA,BLOWING_ALL);
    }

    @Test //第二排吹风模式-吹面
    public void test13_HvacFanDirectionSetModeFace() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_SECOND_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_SECOND_AREA,BLOWING_MODE_FACE);
    }

    @Test //第二排吹风模式-吹地
    public void test14_HvacFanDirectionSetModeLeg() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_SECOND_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_SECOND_AREA,BLOWING_MODE_LEG);
    }

    @Test //第二排吹风模式-吹地+吹面
    public void test15_HvacFanDirectionSetModeFaceAndLeg() {
        PrepareHvacFanDirectionTestEnv(HVAC_FAN_DIRECTION_SECOND_AREA,1,0);
        delay();
        HvacFanDirectionSet( HVAC_FAN_DIRECTION_SECOND_AREA,BLOWING_MODE_FACE_AND_LEG);
    }

    private static CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                if( carPropertyValue.getAreaId() == HVAC_FAN_DIRECTION_FRONT_AREA) {
                    directionValue_front = (int) carPropertyValue.getValue();
                    synchronized (lock_front) {
                        lock_front.notify();
                    }
                } else if( carPropertyValue.getAreaId() == HVAC_FAN_DIRECTION_SECOND_AREA) {
                    directionValue_second = (int) carPropertyValue.getValue();
                    synchronized (lock_second) {
                        lock_second.notify();
                    }
                }
                Log.d(TAG, "HVAC_FAN_DIRECTION " + carPropertyValue.toString());
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };

    public void lockWait(int area) {
        try {
            if( area == HVAC_FAN_DIRECTION_FRONT_AREA) {
                synchronized (lock_front) {
                    lock_front.wait(2000);
                }
            }else if( area == HVAC_FAN_DIRECTION_SECOND_AREA) {
                synchronized (lock_second) {
                    lock_second.wait(2000);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void HvacFanDirectionAvailTest( boolean expect, int area) {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(HVAC_FAN_DIRECTION, area);
        Log.d(TAG, "HvacFanDirectionAvailTest  value：" + expect  + " area is : " + area + " isAvail is : " + isAvail);
        Assert.assertEquals(expect,isAvail);
    }

    private void HvacFanDirectionSet( int area , int mode ) {
        int bRet = -1;
        Log.d(TAG, "HvacFanDirectionSet set HVAC_FAN_DIRECTION area is: " + area + "  mode is :" + mode);
        mCarPropertyMgr.setIntProperty(HVAC_FAN_DIRECTION, area, mode);
        delay();
        bRet = mCarPropertyMgr.getIntProperty(HVAC_FAN_DIRECTION, area);
        Assert.assertEquals(mode,bRet);
        lockWait(area);
        if( area == HVAC_FAN_DIRECTION_FRONT_AREA ) {
            Assert.assertEquals(mode,directionValue_front);
        } else if( area == HVAC_FAN_DIRECTION_SECOND_AREA) {
            Assert.assertEquals(mode,directionValue_second);
        }
    }


    private void PrepareHvacFanDirectionTestEnv( int areaid ,int avail, int data ) {
        int hvacPowerOnavail_front = 1;
        int hvacPowerData_front = 1;
        int hvacPowerOnavail_second = 1;
        int hvacPowerData_second = 1;

        String  availability_fanDirection = "";
        String data_fanDirection = "";
        String availability_Power_front = "";
        String data_Power_front = "";
        String availability_Power_second = "";
        String data_Power_second = "";

        Log.d(TAG, " PrepareHvacFanDirectionTestEnv areaid is :" + areaid  + "avail：" + avail + " data :" + data);

        if( areaid == HVAC_FAN_DIRECTION_FRONT_AREA ) {
            availability_fanDirection = "paclmodefrstleft.availability";
            data_fanDirection = "paclmodefrstleft.data";
        } else if( areaid == HVAC_FAN_DIRECTION_SECOND_AREA ) {
            availability_fanDirection = "paclmodesec.availability";
            data_fanDirection = "paclmodesec.data";
        }

        availability_Power_front = "paclairctrloff.availability";
        data_Power_front = "paclairctrloff.data";
        availability_Power_second = "paclsecrowonoffswith.availability";
        data_Power_second = "paclsecrowonoffswith.data";

        String[] config_indexs = {availability_fanDirection, data_fanDirection,availability_Power_front,data_Power_front,availability_Power_second,data_Power_second};
        int[] values = {avail, data,hvacPowerOnavail_front,hvacPowerData_front,hvacPowerOnavail_second,hvacPowerData_second};
        ipcpClient.setClimaSignal(SERVICE_ID_CLIMATE, OP_ID_CLIMATE, config_indexs,  values);
    }

    private static void setConfig(int OperId) {
        int climateOperId[] = {OperId};
        ipcpClient.setConfig(SERVICE_ID_CLIMATE, climateOperId);
    }

}
